﻿using System;
using System.Drawing;
using System.Drawing.Imaging;
using Spire.Pdf;
using Spire.Doc;
using Spire.Doc.Documents;
using System.Windows.Forms;
using Spire.Pdf.Conversion;
using Spire.Pdf.Fields;
using Spire.Xls;
using Spire.Presentation;
using System.Reflection;
using System.ComponentModel;
using System.Linq;
using Spire.Xls.Core.Spreadsheet;
using System.Runtime.CompilerServices;
using System.Collections.Generic;

namespace DocConvertor
{
    #region aConvertor
    public interface IConvertor
    {
        /// <summary>
        /// 打开文件过滤扩展名
        /// </summary>
        string OpenFilter { get; }
        /// <summary>
        /// 可输出格式(";"隔开)
        /// </summary>
        string SaveExtensions { get; }
        /// <summary>
        /// 转换文件格式
        /// </summary>
        /// <param name="sourceFileName"></param>
        /// <returns></returns>
        bool Converter(string sourceFileName, string saveExtension, string savePath);
    }
    public abstract class aConvertor : IConvertor
    {
        public abstract string OpenFilter { get; }
        public abstract string SaveExtensions { get; }
        public abstract bool Converter(string sourceFileName, string saveExtension, string savePath);
        /// <summary>
        /// 获取输出文件名称
        /// </summary>
        /// <param name="sourceFileName"></param>
        /// <param name="saveExtension"></param>
        /// <param name="savePath"></param>
        /// <returns></returns>
        public virtual string GetSaveFileName(string sourceFileName, string saveExtension, string savePath)
        {
            string saveFileName = "";
            if (string.IsNullOrWhiteSpace(savePath))
                saveFileName = sourceFileName.Substring(0, sourceFileName.LastIndexOf('.')) + "." + saveExtension;
            else
            {
                sourceFileName = sourceFileName.Substring(sourceFileName.LastIndexOf('\\'));
                saveFileName = System.IO.Path.Combine(savePath, sourceFileName.Substring(0, sourceFileName.LastIndexOf('.'))) + "." + saveExtension;
            }
            return saveFileName;
        }
    }
    #endregion
    #region ConvertorOfd
    public class ConvertorOfd : aConvertor
    {
        public override string OpenFilter { get { return "Ofd 文档(*.ofd)|*.ofd"; } }
        public override string SaveExtensions { get { return "pdf;png;"; } }

        public override bool Converter(string sourceFileName, string saveExtension, string savePath)
        {
            var document = new OfdConverter(sourceFileName);
            //document.Crack();

            var saveFileName = GetSaveFileName(sourceFileName, saveExtension, savePath);
            saveExtension = saveExtension.Trim().ToLower();
            switch (saveExtension)
            {
                case "pdf":
                    document.ToPdf(saveFileName);
                    break;
                case "png":
                    for (int i = 0; i < document.PageCount; i++)
                    {
                        string fileName = String.Format("img-{0}.png", (i + 1).ToString("000"));
                        using (Image image = document.ToImage(i))
                        {
                            System.IO.DirectoryInfo dinfo = new System.IO.DirectoryInfo(saveFileName.Substring(0, saveFileName.LastIndexOf('.') + 1));
                            dinfo.Create();
                            image.Save(dinfo.FullName + "\\" + fileName, ImageFormat.Png);
                        }
                    }
                    break;
            }
            return true;
        }
    }
    #endregion
    #region ConvertorPdf
    public class ConvertorPdf : aConvertor
    {
        public override string OpenFilter { get { return "Pdf 文档(*.pdf)|*.pdf"; } }
        public override string SaveExtensions { get { return "docx;doc;xlsx;pptx;ofd;xps;html;png;svg"; } }
        public override bool Converter(string sourceFileName, string saveExtension, string savePath)
        {
            var document = new PdfDocument(sourceFileName);
            document.Crack();

            var saveFileName = GetSaveFileName(sourceFileName, saveExtension, savePath);
            saveExtension = saveExtension.Trim().ToLower();
            switch (saveExtension)
            {
                case "doc":
                    document.SaveToFile(saveFileName, Spire.Pdf.FileFormat.DOC);
                    break;
                case "docx":
                    document.SaveToFile(saveFileName, Spire.Pdf.FileFormat.DOCX);
                    break;
                case "xlsx":
                    document.SaveToFile(saveFileName, Spire.Pdf.FileFormat.XLSX);
                    break;
                case "pptx":
                    document.SaveToFile(saveFileName, Spire.Pdf.FileFormat.PPTX);
                    break;
                case "ofd":
                    document.SaveToFile(saveFileName, Spire.Pdf.FileFormat.OFD);
                    break;
                case "html":
                    document.SaveToFile(saveFileName, Spire.Pdf.FileFormat.HTML);
                    break;
                case "svg":
                    document.SaveToFile(saveFileName, Spire.Pdf.FileFormat.SVG);
                    break;
                case "png":
                    for (int i = 0; i < document.Pages.Count; i++)
                    {
                        string fileName = String.Format("img-{0}.png", (i + 1).ToString("000"));
                        using (Image image = document.SaveAsImage(i, Spire.Pdf.Graphics.PdfImageType.Metafile, 300, 300))
                        {
                            System.IO.DirectoryInfo dinfo = new System.IO.DirectoryInfo(saveFileName.Substring(0, saveFileName.LastIndexOf('.') + 1));
                            dinfo.Create();
                            image.Save(dinfo.FullName + "\\" + fileName, ImageFormat.Png);
                        }
                    }
                    break;
            }
            return true;
        }
    }
    #endregion
    #region ConvertorWord
    public class ConvertorWord : aConvertor
    {
        public override string OpenFilter { get { return "Word 文档(*.doc;*.docx)|*.doc;*.docx"; } }
        public override string SaveExtensions { get { return "pdf;ofd;rtf;html;png;svg;wps"; } }
        public override bool Converter(string sourceFileName, string saveExtension, string savePath)
        {
            var document = new Spire.Doc.Document(sourceFileName, Spire.Doc.FileFormat.Auto);
            document.Crack();

            var saveFileName = GetSaveFileName(sourceFileName, saveExtension, savePath);
            saveExtension = saveExtension.Trim().ToLower();
            switch (saveExtension)
            {
                case "pdf":
                    document.SaveToFile(saveFileName, Spire.Doc.FileFormat.PDF);
                    break;
                case "ofd":
                    document.SaveToFile(saveFileName, Spire.Doc.FileFormat.OFD);
                    break;
                case "rtf":
                    document.SaveToFile(saveFileName, Spire.Doc.FileFormat.Rtf);
                    break;
                case "wps":
                    document.SaveToFile(saveFileName, Spire.Doc.FileFormat.Wps);
                    break;
                case "html":
                    document.SaveToFile(saveFileName, Spire.Doc.FileFormat.Html);
                    break;
                case "svg":
                    document.SaveToFile(saveFileName, Spire.Doc.FileFormat.SVG);
                    break;
                case "png":
                    Image[] Images = document.SaveToImages(Spire.Doc.Documents.ImageType.Bitmap);
                    if (Images != null && Images.Length > 0)
                    {
                        if (Images.Length == 1)
                        {
                            Images[0].Save(saveFileName, ImageFormat.Bmp);
                        }
                        else
                        {
                            for (int i = 0; i < Images.Length; i++)
                            {
                                String fileName = String.Format("img-{0}.png", (i + 1).ToString("000"));
                                System.IO.DirectoryInfo dinfo = new System.IO.DirectoryInfo(saveFileName.Substring(0, saveFileName.LastIndexOf('.') + 1));
                                dinfo.Create();
                                Images[i].Save(dinfo.FullName + "\\" + fileName, ImageFormat.Png);
                            }
                        }
                    }
                    break;
            }
            return true;
        }
    }
    #endregion
    #region ConvertorExcel
    public class ConvertorExcel : aConvertor
    {
        public override string OpenFilter { get { return "Excel 文档(*.xls;*.xlsx)|*.xls;*.xlsx"; } }
        public override string SaveExtensions { get { return "pdf;ofd;csv;html;bitmap"; } }
        public override bool Converter(string sourceFileName, string saveExtension, string savePath)
        {
            var document = new Workbook();
            document.Crack();

            document.LoadFromFile(sourceFileName);
            var saveFileName = GetSaveFileName(sourceFileName, saveExtension, savePath);

            saveExtension = saveExtension.Trim().ToLower();
            switch (saveExtension)
            {
                case "pdf":
                    document.SaveToFile(saveFileName, Spire.Xls.FileFormat.PDF);
                    break;
                case "ofd":
                    document.SaveToFile(saveFileName, Spire.Xls.FileFormat.OFD);
                    break;
                case "csv":
                    document.SaveToFile(saveFileName, Spire.Xls.FileFormat.CSV);
                    break;
                case "html":
                    document.SaveToFile(saveFileName, Spire.Xls.FileFormat.HTML);
                    break;
                case "bitmap":
                    document.SaveToFile(saveFileName, Spire.Xls.FileFormat.Bitmap);
                    break;
            }
            return true;
        }
    }
    #endregion
    #region ConvertorPPT
    public class ConvertorPPT : aConvertor
    {
        public override string OpenFilter { get { return "PPT 文档(*.ppt;*.pptx)|*.ppt;*.pptx"; } }
        public override string SaveExtensions { get { return "pdf;ofd;html;tiff"; } }
        public override bool Converter(string sourceFileName, string saveExtension, string savePath)
        {
            var document = new Presentation(sourceFileName, Spire.Presentation.FileFormat.Auto);
            document.Crack();

            var saveFileName = GetSaveFileName(sourceFileName, saveExtension, savePath);
            saveExtension = saveExtension.Trim().ToLower();
            switch (saveExtension)
            {
                case "pdf":
                    document.SaveToFile(saveFileName, Spire.Presentation.FileFormat.PDF);
                    break;
                case "ofd":
                    document.SaveToFile(saveFileName, Spire.Presentation.FileFormat.OFD);
                    break;
                case "html":
                    document.SaveToFile(saveFileName, Spire.Presentation.FileFormat.Html);
                    break;
                case "tiff":
                    document.SaveToFile(saveFileName, Spire.Presentation.FileFormat.Tiff);
                    break;
            }
            return true;
        }
    }
    #endregion

    #region SpireOfficeHelpers
    public static class SpireOfficeHelpers
    {
        /// <summary>
        /// 注入激活信息
        /// </summary>
        /// <param name="document"></param>
        public static void Crack(this OfdConverter document)
        {
            InjectLicense(document);
        }
        /// <summary>
        /// 注入激活信息
        /// </summary>
        /// <param name="workbook"></param>
        public static void Crack(this Workbook workbook)
        {
            InjectLicense(workbook);
        }
        /// <summary>
        /// 注入激活信息
        /// </summary>
        /// <param name="document"></param>
        public static void Crack(this Spire.Doc.Document document)
        {
            InjectLicense(document);
        }
        /// <summary>
        /// 注入激活信息
        /// </summary>
        /// <param name="document"></param>
        public static void Crack(this PdfDocument document)
        {
            InjectLicense(document);
        }
        /// <summary>
        /// 注入激活信息
        /// </summary>
        /// <param name="document"></param>
        public static void Crack(this Presentation document)
        {
            InjectLicense(document);
        }
        /// <summary>
        /// 注入激活信息，并返回该类型
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <returns></returns>
        public static T InjectLicense<T>(T t) where T : class
        {
            //return t;
            try
            {
                //var LData = "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiIHN0YW5kYWxvbmU9InllcyI/Pgo8TGljZW5zZSBLZXk9ImNyOERaN1hKMkR5MUs2UUJBTkRPSVRLdlpjTzZkelVod2lsSHBnVlluQ3k0cXlHV2V6TFZubFJGeFAxNU1mSWZnUmdNWm1XaEdOQWRFNFRqZWZnQ1ovbFR2b1BkSXRIbDZXdDVBNWk1TVhFbnFkQnVPMUthRnovRFFzYUdWTGhzdjlySG1ybnRxSElFRGxJeGRxYUpNcGtLb0Frd1A3d1N6T01KMVkrbUNmVTVVRmV6REwvTjd1enJ4M0Y0d2I1SGErd0E2VFQ5VFJ3SzAzejlFS01aRmwzU1lSL3o0YVU3TE0wZFNYWTlqU0ZKZ2dqZlZzRFVLaUJyVm5td1ljaXVyOUVrYmw5Q3RaWTAzdG1yZm01QlplKzZnaHRFTm4wb2gzMzh0WlJleWpjcjc0QWs3MWhnWWtuTE9CQzE1VllmalhzcXVBVW13MlI2TWNWMlBPT2JyY1RSYlhBZ3pvUWJPeWQ4U2JFWmN3aE43NktQd1dzUVFTMUowdGlZSFVLeE9tMnQ0ZkJWMGhQVmhhOUI4Y0swNHFKUVp0MDBaMWNKRGEwd2I4VWx6RWs5QkhVVzJlbk9mVDE0UnlIQ2krWUdlbVBLY2RDUXJoMXpyWVRGN0ltb0x4N3h1NGV2RFRZc2xzV0JrbFFJb3g4NnJWckVVa1N0dXErQUNTWS9xVTM5L1Zhd3Y5S0FmUjVUZUVicGt3RGhTYjBOQkFqVDhBeXRsRFZkR2ZpZzBxS0czVllpVHBYRnc1cHRMVmgrYmtkK2RnN3Z4dHZyNDVaVVdKZXlyekdOR0g3YUZZZDZwLzJNRy9YSlRsR3ovU05RbzJDUExraU83SlhuOU5HZXhaN3BIbTBkZ3pNWmJHRVhxVmR2bG04MTJhL1hMMVNxeEdVWStvNVpsVUM3WTV4Z2dhRCtGZVA5enpoeUpxSUVwcDk3My9ScTRteG1wQWZMcVNzTzJSeHlTcStpdjFDc3AwQ3JvMDc4OEhybDFteWt4dVQweWRSWVpDNkRTeDhNMi9MWTNkOXNud3U3NkFmYjVDOVF1ZE9Zc0wzREh2aGZncmNVSWUvcUhmVFo5QWF6Y3pUanlyM2RPQkFjczBLZk12Y0xVUzRSeHZDdW1NNDVyNDJnMXJ3UGluN2JBcmYvZnNMTzZtS3g0WWRoSURNWlF6V3RjbkhFSTF5TXJ6aU9pdXhMdE8xalRBV25uU2VLVDJ0cXI3Tm42Qmg5TURHNjZZK2lJaW4xV05TUCtMdDFYdXRkajNKTyt4b1FNUVB5ZFpoZkJYZXpVMEhRMnd0eEdwdzRNczRTMTVJbFg1TEdXR3dXeUdYTWNjVWd3b1RDeFRGYmgyZFo0Vkg3OVZHTEVFR1JRWEZrNTRBdlFLdFBpdUcxY0w4RFo3WEoyRHkxSzZUUWVORE9YeFl2NFNveitCMHNBS0VwTVRrNCtTYWpYNksrSjlUOFhZVXRTOE8wWWZGUFZqZkhIYTZORWQyODdVcUlqMnJnQlF1bjVDV3hCczFHUm5BYmd1Z3MyL2ZQakcwZmdQemdSYzR5Q3ZObFg4V2pKUnloc3U5VFRKTjd1R3NOdnprU2IyZWlyQmhEaG1vQ0Jqa0wyYnMzT3I2d2pnNnBUNVpmNGhEdDF0STBJNXo1aytxQXVSZnRhd1lmamhXYmpMS0xKOTlUVk1kRDZaTCtTenNtQkNWN05lYm96V0RUTWgrRnJPT292R09ZbUk1bWp4Smd1MVRXNnI1V0JUK2oxSjBFNmJIb2tEMWo0Wm1DWUQreVBPUW1PMm1yUTNGdC9jVmZwQWlJdzliRkgwZ1FIbXQ4QnNuZnQ2MVV3c1h6cSs2akNvY1hOOUMvRXZPblhTczZuVlNGSkVBL3l1QmNIazZxOWdqanBnRG1NTEcrNlpxR1VjRWMzZEp2THpuK3pNT0p3TDI4WUQxN3BLSXBUNnd6WFBFVFJwWS9qNHhoMkQvaFhJRVNHcTk1eTVmZE9MNmx1QT09IiBWZXJzaW9uPSI5LjkiPgogICAgPFR5cGU+UnVudGltZTwvVHlwZT4KICAgIDxVc2VybmFtZT5Vc2VyTmFtZTwvVXNlcm5hbWU+CiAgICA8RW1haWw+ZU1haWxAaG9zdC5jb208L0VtYWlsPgogICAgPE9yZ2FuaXphdGlvbj5Pcmdhbml6YXRpb248L09yZ2FuaXphdGlvbj4KICAgIDxMaWNlbnNlZERhdGU+MjAxNi0wMS0wMVQxMjowMDowMFo8L0xpY2Vuc2VkRGF0ZT4KICAgIDxFeHBpcmVkRGF0ZT4yMDk5LTEyLTMxVDEyOjAwOjAwWjwvRXhwaXJlZERhdGU+CiAgICA8UHJvZHVjdHM+CiAgICAgICAgPFByb2R1Y3Q+CiAgICAgICAgICAgIDxOYW1lPlNwaXJlLk9mZmljZSBQbGF0aW51bTwvTmFtZT4KICAgICAgICAgICAgPFZlcnNpb24+OS45OTwvVmVyc2lvbj4KICAgICAgICAgICAgPFN1YnNjcmlwdGlvbj4KICAgICAgICAgICAgICAgIDxOdW1iZXJPZlBlcm1pdHRlZERldmVsb3Blcj45OTk5OTwvTnVtYmVyT2ZQZXJtaXR0ZWREZXZlbG9wZXI+CiAgICAgICAgICAgICAgICA8TnVtYmVyT2ZQZXJtaXR0ZWRTaXRlPjk5OTk5PC9OdW1iZXJPZlBlcm1pdHRlZFNpdGU+CiAgICAgICAgICAgIDwvU3Vic2NyaXB0aW9uPgogICAgICAgIDwvUHJvZHVjdD4KICAgIDwvUHJvZHVjdHM+CiAgICA8SXNzdWVyPgogICAgICAgIDxOYW1lPklzc3VlcjwvTmFtZT4KICAgICAgICA8RW1haWw+aXNzdWVyQGlzc3Vlci5jb208L0VtYWlsPgogICAgICAgIDxVcmw+aHR0cDovL3d3dy5pc3N1ZXIuY29tPC9Vcmw+CiAgICA8L0lzc3Vlcj4KPC9MaWNlbnNlPg==";
                //Spire.License.LicenseProvider.SetLicenseKey(LData);

                if (t == null) return t;
                foreach (var item in t.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance))
                {
                    if (item.FieldType == typeof(XlsWorkbook))
                    {
                        var xwb = item.GetValue(t);
                        if (xwb != null)
                            InjectLicense(xwb);
                    }
                }

                var InternalLicense = t.GetType().GetProperty("InternalLicense", BindingFlags.NonPublic | BindingFlags.Instance);
                if (InternalLicense == null) return t;
                if (InternalLicense.CanRead)
                {
                    var il = InternalLicense.GetValue(t, null);
                }
                var TypeLic = Activator.CreateInstance(InternalLicense.PropertyType, true);
                foreach (var item in TypeLic.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance))
                {
                    if (item.FieldType.IsArray)
                    {
                        item.SetValue(TypeLic, new string[] { "Spire.OfficeViewer.Forms", "Spire.Office", "Spire.XLS", "Spire.Doc", "Spire.Presentation", "Spire.Spreadsheet", "Spire.DocViewer.Wpf" });
                    }
                    else if (item.FieldType.IsEnum)
                    {
                        item.SetValue(TypeLic, 3);
                    }
                }
                if (InternalLicense.CanWrite)
                    InternalLicense.SetValue(t, TypeLic, null);
            }
            catch (Exception ex)
            { }
            return t;
        }
    }
    public static class Extents
    {
        public static List<Assembly> GetReferanceAssemblies(this AppDomain domain)
        {
            var list = new List<Assembly>();
           foreach(var i in domain.GetAssemblies())
            {
                GetReferanceAssemblies(i, list);
            }
            return list;
        }
        static void GetReferanceAssemblies(Assembly assembly, List<Assembly> list)
        {
            foreach (var i in assembly.GetReferencedAssemblies())
            {
                var ass = Assembly.Load(i);
                if (!list.Contains(ass))
                {
                    list.Add(ass);
                    GetReferanceAssemblies(ass, list);
                }
            }
        }
    }
    public static class SpireHelper
    {
        public static void ActivateMemoryPatching()
        {
            var arr = AppDomain.CurrentDomain.GetReferanceAssemblies();
            foreach (Assembly assembly in arr)
            {
                if (assembly.FullName.StartsWith("Spire.Pdf"))
                    ActivateForAssembly(assembly);
                //var ss = assembly.GetTypes();
                //foreach (var assembly2 in ss)
                //{
                //    if (assembly2.FullName.StartsWith("Spire.License"))
                //        ActivateForAssembly(assembly);
                //}
            }
            AppDomain.CurrentDomain.AssemblyLoad += new AssemblyLoadEventHandler(ActivateOnLoad);
        }

        private static void ActivateOnLoad(object sender, AssemblyLoadEventArgs e)
        {
            string Name = e.LoadedAssembly.FullName;
            if (Name.IndexOf("Spire.License") != -1)
                ActivateForAssembly(e.LoadedAssembly);
        }

        private static void ActivateForAssembly(Assembly assembly)
        {
            bool isFound = false;

            Type[] arrType = null;
            try
            {
                arrType = assembly.GetTypes();
            }
            catch (ReflectionTypeLoadException err)
            {
                arrType = err.Types;
            }

            MethodInfo miLicensed = typeof(SpireHelper).GetMethod("InvokeMe", BindingFlags.NonPublic | BindingFlags.Static);
            MethodInfo miEvaluation = null;

            foreach (Type type in arrType)
            {
                if (isFound) break;

                if (type == null) continue;

                MethodInfo[] arrMInfo = type.GetMethods(BindingFlags.NonPublic | BindingFlags.Static);

                foreach (MethodInfo info in arrMInfo)
                {
                    if (isFound) break;

                    try
                    {
                        string strMethod = info.ToString();
                        if ((strMethod.StartsWith("Byte[]")) && (strMethod.IndexOf("(System.String)") > 0))
                        {
                            miEvaluation = info;
                            MemoryPatching(miEvaluation, miLicensed);
                            isFound = true;
                            break;
                        }
                    }
                    catch
                    {
                        throw new InvalidOperationException("MemoryPatching for " + assembly.FullName + " failed !");
                    }
                }
            }

            string LData = "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiIHN0YW5kYWxvbmU9InllcyI/Pgo8TGljZW5zZSBLZXk9ImNyOERaN1hKMkR5MUs2UUJBTkRPSVRLdlpjTzZkelVod2lsSHBnVlluQ3k0cXlHV2V6TFZubFJGeFAxNU1mSWZnUmdNWm1XaEdOQWRFNFRqZWZnQ1ovbFR2b1BkSXRIbDZXdDVBNWk1TVhFbnFkQnVPMUthRnovRFFzYUdWTGhzdjlySG1ybnRxSElFRGxJeGRxYUpNcGtLb0Frd1A3d1N6T01KMVkrbUNmVTVVRmV6REwvTjd1enJ4M0Y0d2I1SGErd0E2VFQ5VFJ3SzAzejlFS01aRmwzU1lSL3o0YVU3TE0wZFNYWTlqU0ZKZ2dqZlZzRFVLaUJyVm5td1ljaXVyOUVrYmw5Q3RaWTAzdG1yZm01QlplKzZnaHRFTm4wb2gzMzh0WlJleWpjcjc0QWs3MWhnWWtuTE9CQzE1VllmalhzcXVBVW13MlI2TWNWMlBPT2JyY1RSYlhBZ3pvUWJPeWQ4U2JFWmN3aE43NktQd1dzUVFTMUowdGlZSFVLeE9tMnQ0ZkJWMGhQVmhhOUI4Y0swNHFKUVp0MDBaMWNKRGEwd2I4VWx6RWs5QkhVVzJlbk9mVDE0UnlIQ2krWUdlbVBLY2RDUXJoMXpyWVRGN0ltb0x4N3h1NGV2RFRZc2xzV0JrbFFJb3g4NnJWckVVa1N0dXErQUNTWS9xVTM5L1Zhd3Y5S0FmUjVUZUVicGt3RGhTYjBOQkFqVDhBeXRsRFZkR2ZpZzBxS0czVllpVHBYRnc1cHRMVmgrYmtkK2RnN3Z4dHZyNDVaVVdKZXlyekdOR0g3YUZZZDZwLzJNRy9YSlRsR3ovU05RbzJDUExraU83SlhuOU5HZXhaN3BIbTBkZ3pNWmJHRVhxVmR2bG04MTJhL1hMMVNxeEdVWStvNVpsVUM3WTV4Z2dhRCtGZVA5enpoeUpxSUVwcDk3My9ScTRteG1wQWZMcVNzTzJSeHlTcStpdjFDc3AwQ3JvMDc4OEhybDFteWt4dVQweWRSWVpDNkRTeDhNMi9MWTNkOXNud3U3NkFmYjVDOVF1ZE9Zc0wzREh2aGZncmNVSWUvcUhmVFo5QWF6Y3pUanlyM2RPQkFjczBLZk12Y0xVUzRSeHZDdW1NNDVyNDJnMXJ3UGluN2JBcmYvZnNMTzZtS3g0WWRoSURNWlF6V3RjbkhFSTF5TXJ6aU9pdXhMdE8xalRBV25uU2VLVDJ0cXI3Tm42Qmg5TURHNjZZK2lJaW4xV05TUCtMdDFYdXRkajNKTyt4b1FNUVB5ZFpoZkJYZXpVMEhRMnd0eEdwdzRNczRTMTVJbFg1TEdXR3dXeUdYTWNjVWd3b1RDeFRGYmgyZFo0Vkg3OVZHTEVFR1JRWEZrNTRBdlFLdFBpdUcxY0w4RFo3WEoyRHkxSzZUUWVORE9YeFl2NFNveitCMHNBS0VwTVRrNCtTYWpYNksrSjlUOFhZVXRTOE8wWWZGUFZqZkhIYTZORWQyODdVcUlqMnJnQlF1bjVDV3hCczFHUm5BYmd1Z3MyL2ZQakcwZmdQemdSYzR5Q3ZObFg4V2pKUnloc3U5VFRKTjd1R3NOdnprU2IyZWlyQmhEaG1vQ0Jqa0wyYnMzT3I2d2pnNnBUNVpmNGhEdDF0STBJNXo1aytxQXVSZnRhd1lmamhXYmpMS0xKOTlUVk1kRDZaTCtTenNtQkNWN05lYm96V0RUTWgrRnJPT292R09ZbUk1bWp4Smd1MVRXNnI1V0JUK2oxSjBFNmJIb2tEMWo0Wm1DWUQreVBPUW1PMm1yUTNGdC9jVmZwQWlJdzliRkgwZ1FIbXQ4QnNuZnQ2MVV3c1h6cSs2akNvY1hOOUMvRXZPblhTczZuVlNGSkVBL3l1QmNIazZxOWdqanBnRG1NTEcrNlpxR1VjRWMzZEp2THpuK3pNT0p3TDI4WUQxN3BLSXBUNnd6WFBFVFJwWS9qNHhoMkQvaFhJRVNHcTk1eTVmZE9MNmx1QT09IiBWZXJzaW9uPSI5LjkiPgogICAgPFR5cGU+UnVudGltZTwvVHlwZT4KICAgIDxVc2VybmFtZT5Vc2VyTmFtZTwvVXNlcm5hbWU+CiAgICA8RW1haWw+ZU1haWxAaG9zdC5jb208L0VtYWlsPgogICAgPE9yZ2FuaXphdGlvbj5Pcmdhbml6YXRpb248L09yZ2FuaXphdGlvbj4KICAgIDxMaWNlbnNlZERhdGU+MjAxNi0wMS0wMVQxMjowMDowMFo8L0xpY2Vuc2VkRGF0ZT4KICAgIDxFeHBpcmVkRGF0ZT4yMDk5LTEyLTMxVDEyOjAwOjAwWjwvRXhwaXJlZERhdGU+CiAgICA8UHJvZHVjdHM+CiAgICAgICAgPFByb2R1Y3Q+CiAgICAgICAgICAgIDxOYW1lPlNwaXJlLk9mZmljZSBQbGF0aW51bTwvTmFtZT4KICAgICAgICAgICAgPFZlcnNpb24+OS45OTwvVmVyc2lvbj4KICAgICAgICAgICAgPFN1YnNjcmlwdGlvbj4KICAgICAgICAgICAgICAgIDxOdW1iZXJPZlBlcm1pdHRlZERldmVsb3Blcj45OTk5OTwvTnVtYmVyT2ZQZXJtaXR0ZWREZXZlbG9wZXI+CiAgICAgICAgICAgICAgICA8TnVtYmVyT2ZQZXJtaXR0ZWRTaXRlPjk5OTk5PC9OdW1iZXJPZlBlcm1pdHRlZFNpdGU+CiAgICAgICAgICAgIDwvU3Vic2NyaXB0aW9uPgogICAgICAgIDwvUHJvZHVjdD4KICAgIDwvUHJvZHVjdHM+CiAgICA8SXNzdWVyPgogICAgICAgIDxOYW1lPklzc3VlcjwvTmFtZT4KICAgICAgICA8RW1haWw+aXNzdWVyQGlzc3Vlci5jb208L0VtYWlsPgogICAgICAgIDxVcmw+aHR0cDovL3d3dy5pc3N1ZXIuY29tPC9Vcmw+CiAgICA8L0lzc3Vlcj4KPC9MaWNlbnNlPg==";

            //Spire.License.LicenseProvider.SetLicenseKey(LData);
            Type type2 = assembly.GetType("Spire.License.LicenseProvider");
            MethodInfo mi = type2.GetMethod("SetLicenseKey", new Type[] { typeof(String) });
            mi.Invoke(Activator.CreateInstance(type2, null), new String[] { LData });
        }


        private static byte[] InvokeMe(String string_0)
        {
            return Convert.FromBase64String("PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiIHN0YW5kYWxvbmU9InllcyI/Pgo8TGljZW5zZSBLZXk9IngiIFZlcnNpb249IjkuOSI+CiAgICA8VHlwZT5SdW50aW1lPC9UeXBlPgogICAgPFVzZXJuYW1lPlVzZXJOYW1lPC9Vc2VybmFtZT4KICAgIDxFbWFpbD5lTWFpbEBob3N0LmNvbTwvRW1haWw+CiAgICA8T3JnYW5pemF0aW9uPk9yZ2FuaXphdGlvbjwvT3JnYW5pemF0aW9uPgogICAgPExpY2Vuc2VkRGF0ZT4yMDE2LTAxLTAxVDEyOjAwOjAwWjwvTGljZW5zZWREYXRlPgogICAgPEV4cGlyZWREYXRlPjIwOTktMTItMzFUMTI6MDA6MDBaPC9FeHBpcmVkRGF0ZT4KICAgIDxQcm9kdWN0cz4KICAgICAgICA8UHJvZHVjdD4KICAgICAgICAgICAgPE5hbWU+U3BpcmUuT2ZmaWNlIFBsYXRpbnVtPC9OYW1lPgogICAgICAgICAgICA8VmVyc2lvbj45Ljk5PC9WZXJzaW9uPgogICAgICAgICAgICA8U3Vic2NyaXB0aW9uPgogICAgICAgICAgICAgICAgPE51bWJlck9mUGVybWl0dGVkRGV2ZWxvcGVyPjk5OTk5PC9OdW1iZXJPZlBlcm1pdHRlZERldmVsb3Blcj4KICAgICAgICAgICAgICAgIDxOdW1iZXJPZlBlcm1pdHRlZFNpdGU+OTk5OTk8L051bWJlck9mUGVybWl0dGVkU2l0ZT4KICAgICAgICAgICAgPC9TdWJzY3JpcHRpb24+CiAgICAgICAgPC9Qcm9kdWN0PgogICAgPC9Qcm9kdWN0cz4KICAgIDxJc3N1ZXI+CiAgICAgICAgPE5hbWU+SXNzdWVyPC9OYW1lPgogICAgICAgIDxFbWFpbD5pc3N1ZXJAaXNzdWVyLmNvbTwvRW1haWw+CiAgICAgICAgPFVybD5odHRwOi8vd3d3Lmlzc3Vlci5jb208L1VybD4KICAgIDwvSXNzdWVyPgo8L0xpY2Vuc2U+Cg==");
        }

        private static unsafe void MemoryPatching(MethodBase miEvaluation, MethodBase miLicensed)
        {
            IntPtr IntPtrEval = GetMemoryAddress(miEvaluation);
            IntPtr IntPtrLicensed = GetMemoryAddress(miLicensed);

            if (IntPtr.Size == 8)
                *((long*)IntPtrEval.ToPointer()) = *((long*)IntPtrLicensed.ToPointer());
            else
                *((int*)IntPtrEval.ToPointer()) = *((int*)IntPtrLicensed.ToPointer());
        }

        private static unsafe IntPtr GetMemoryAddress(MethodBase mb)
        {
            RuntimeHelpers.PrepareMethod(mb.MethodHandle);

            if ((Environment.Version.Major >= 4) || ((Environment.Version.Major == 2) && (Environment.Version.MinorRevision >= 3053)))
            {
                return new IntPtr(((int*)mb.MethodHandle.Value.ToPointer() + 2));
            }

            UInt64* location = (UInt64*)(mb.MethodHandle.Value.ToPointer());
            int index = (int)(((*location) >> 32) & 0xFF);
            if (IntPtr.Size == 8)
            {
                ulong* classStart = (ulong*)mb.DeclaringType.TypeHandle.Value.ToPointer();
                ulong* address = classStart + index + 10;
                return new IntPtr(address);
            }
            else
            {
                uint* classStart = (uint*)mb.DeclaringType.TypeHandle.Value.ToPointer();
                uint* address = classStart + index + 10;
                return new IntPtr(address);
            }
        }
    }
    class SpireOfficePatch
    {
        //static object licenseCache;
        //[HarmonyLib.HarmonyPatch(typeof(Spire.License.LicenseProvider), "GetLicense")]
        //[HarmonyLib.HarmonyPrefix]
        //static bool Prefix_SpireOffice_LicenseProvider_GetLicense(LicenseContext context, Type type, object instance, bool allowExceptions, ref object __result, MethodInfo __originalMethod)
        //{
        //    if (licenseCache != null)
        //    {
        //        //有构建过 的 直接拦截返回 
        //        __result = licenseCache;
        //        return false;
        //    }
        //    var declaringType = __originalMethod.DeclaringType;
        //    MethodInfo tempMethod = HarmonyLib.AccessTools.FirstMethod(declaringType, m => m.GetParameters().Any() && m.GetParameters()[0].ParameterType == typeof(System.IO.Stream) && m.ReturnType != typeof(void));
        //    if (tempMethod != null)
        //    {
        //        var licType = tempMethod.ReturnType;
        //        //构建 license对象 然后 给关键点赋值 （这里就脱敏处理 不提供完整逻辑了            
        //        var o = Activator.CreateInstance(licType);
        //        try
        //        {
        //            foreach (var item in licType.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance))
        //            {
        //                try
        //                {
        //                    if (item.FieldType.IsArray)
        //                    {
        //                        item.SetValue(o, new string[] { "Spire.Spreadsheet", "Spire.DocViewer.Wpf" });
        //                    }
        //                    else if (item.FieldType.IsEnum)
        //                    {
        //                        item.SetValue(o, 3);
        //                    }
        //                    else
        //                    {
        //                        item.SetValue(o, null);
        //                    }
        //                }
        //                catch (Exception ex)
        //                { }
        //            }
        //            //o.SetValue(t, licType, null);
        //        }
        //        catch (Exception ex)
        //        { }
        //        //........给 license对象 o的 关键字段 反射赋值（这里就脱敏处理 不提供完整逻辑了     

        //        //直接缓存  license对象 并拦截返回值 返回上面 自行构建的对象，这样 直接跳过后续的一大段验证逻辑。
        //        __result = licenseCache = o;
        //        return false;


        //    }
        //    return true;
        //}

        //internal static void Patch()
        //{
        //    HarmonyLib.Harmony.CreateAndPatchAll(typeof(SpireOfficePatch), nameof(SpireOfficePatch));
        //}
    }
    #endregion

}
